<script setup lang="ts">
import type {
  EventBinding,
  EventsFacet,
  EventSubscription,
} from '#/api/resource-center/types';

import { computed, reactive, ref } from 'vue';

import { IconifyIcon } from '@vben/icons';

import { message } from 'ant-design-vue';

// Props
interface Props {
  events?: EventsFacet;
}

const props = defineProps<Props>();

// Emits
const emit = defineEmits<{
  update: [events: EventsFacet];
}>();

// 响应式数据
const publishModalVisible = ref(false);
const subscribeModalVisible = ref(false);
const editingSubscription = ref<EventSubscription | null>(null);

// 表单数据
const publishForm = reactive({
  eventType: '',
  description: '',
  schema: '',
});

const subscribeForm = reactive({
  eventType: '',
  mode: 'SYNC',
  filter: '',
  handler: {
    actions: [] as any[],
  },
});

// 计算属性
const events = computed(() => props.events || { publish: [], subscribe: [] });

// 方法
const getHandlerDescription = (handler: any) => {
  if (!handler?.actions?.length) return '无处理器';
  const actionTypes = handler.actions
    .map((action: any) => action.type)
    .join(', ');
  return `${handler.actions.length}个动作: ${actionTypes}`;
};

const showAddPublishModal = () => {
  resetPublishForm();
  publishModalVisible.value = true;
};

const savePublishEvent = () => {
  if (!publishForm.eventType) {
    message.error('请输入事件类型');
    return;
  }

  const newEvent: EventBinding = {
    eventType: publishForm.eventType,
    description: publishForm.description,
    schema: publishForm.schema ? JSON.parse(publishForm.schema) : undefined,
  };

  const currentPublish = events.value.publish || [];
  const newPublish = [...currentPublish, newEvent];

  emit('update', {
    ...events.value,
    publish: newPublish,
  });

  message.success('发布事件添加成功');
  publishModalVisible.value = false;
  resetPublishForm();
};

const cancelPublishEvent = () => {
  publishModalVisible.value = false;
  resetPublishForm();
};

const resetPublishForm = () => {
  publishForm.eventType = '';
  publishForm.description = '';
  publishForm.schema = '';
};

const deletePublishEvent = (eventType: string) => {
  const newPublish =
    events.value.publish?.filter((e) => e.eventType !== eventType) || [];
  emit('update', {
    ...events.value,
    publish: newPublish,
  });
  message.success('发布事件删除成功');
};

const editPublishEvent = (event: EventBinding) => {
  publishForm.eventType = event.eventType;
  publishForm.description = event.description || '';
  publishForm.schema = event.schema
    ? JSON.stringify(event.schema, null, 2)
    : '';
  event.schemaJSON.stringifyevent.schemaJSON.stringify;
  publishModalVisible.value = true;
};

const showAddSubscribeModal = () => {
  editingSubscription.value = null;
  resetSubscribeForm();
  subscribeModalVisible.value = true;
};

const editSubscribeEvent = (subscription: EventSubscription) => {
  editingSubscription.value = subscription;
  subscribeForm.eventType = subscription.eventType;
  subscribeForm.mode = subscription.mode || 'SYNC';
  subscribeForm.filter = subscription.filter || '';
  subscribeForm.handler.actions = [...(subscription.handler?.actions || [])];
  subscribeModalVisible.value = true;
};

const saveSubscribeEvent = () => {
  if (!subscribeForm.eventType) {
    message.error('请输入事件类型');
    return;
  }

  const newSubscription: EventSubscription = {
    eventType: subscribeForm.eventType,
    mode: subscribeForm.mode,
    filter: subscribeForm.filter || undefined,
    handler: {
      actions: [...subscribeForm.handler.actions],
    },
  };

  const currentSubscribe = events.value.subscribe || [];
  let newSubscribe: EventSubscription[];

  if (editingSubscription.value) {
    // 编辑模式
    newSubscribe = currentSubscribe.map((s) =>
      s.eventType === editingSubscription.value!.eventType
        ? newSubscription
        : s,
    );
  } else {
    // 新增模式
    newSubscribe = [...currentSubscribe, newSubscription];
  }

  emit('update', {
    ...events.value,
    subscribe: newSubscribe,
  });

  message.success(
    editingSubscription.value ? '订阅事件更新成功' : '订阅事件添加成功',
  );
  subscribeModalVisible.value = false;
  resetSubscribeForm();
};

const cancelSubscribeEvent = () => {
  subscribeModalVisible.value = false;
  resetSubscribeForm();
};

const resetSubscribeForm = () => {
  subscribeForm.eventType = '';
  subscribeForm.mode = 'SYNC';
  subscribeForm.filter = '';
  subscribeForm.handler.actions = [];
};

const deleteSubscribeEvent = (eventType: string) => {
  const newSubscribe =
    events.value.subscribe?.filter((s) => s.eventType !== eventType) || [];
  emit('update', {
    ...events.value,
    subscribe: newSubscribe,
  });
  message.success('订阅事件删除成功');
};

// 处理器编辑器方法
const addHandlerAction = () => {
  subscribeForm.handler.actions.push({
    type: 'CALL_BEHAVIOR',
    params: '',
  });
};

const removeHandlerAction = (index: number) => {
  subscribeForm.handler.actions.splice(index, 1);
};

const moveHandlerAction = (index: number, direction: 'down' | 'up') => {
  const actions = subscribeForm.handler.actions;
  if (direction === 'up' && index > 0) {
    [actions[index], actions[index - 1]] = [actions[index - 1], actions[index]];
  } else if (direction === 'down' && index < actions.length - 1) {
    [actions[index], actions[index + 1]] = [actions[index + 1], actions[index]];
  }
};
</script>

<template>
  <div class="resource-events">
    <!-- 事件管理头部 -->
    <div class="events-header">
      <h3>事件管理</h3>
      <a-space>
        <a-button type="primary" @click="showAddPublishModal">
          <template #icon>
            <IconifyIcon icon="ant-design:plus-outlined" />
          </template>
          添加发布事件
        </a-button>
        <a-button @click="showAddSubscribeModal">
          <template #icon>
            <IconifyIcon icon="ant-design:plus-outlined" />
          </template>
          添加订阅事件
        </a-button>
      </a-space>
    </div>

    <!-- 事件配置内容 -->
    <div class="events-content">
      <!-- 发布事件 -->
      <a-card title="发布事件" class="events-card">
        <div class="publish-events">
          <a-empty v-if="!events?.publish?.length" description="暂无发布事件" />

          <div v-else class="events-list">
            <a-card
              v-for="event in events.publish"
              :key="event.eventType"
              class="event-card"
              size="small"
            >
              <template #title>
                <div class="event-title">
                  <span>{{ event.eventType }}</span>
                  <a-tag color="green" size="small">发布</a-tag>
                </div>
              </template>

              <div class="event-actions">
                <a-button
                  type="link"
                  size="small"
                  @click="editPublishEvent(event)"
                >
                  编辑
                </a-button>
                <a-popconfirm
                  title="确定要删除这个发布事件吗？"
                  @confirm="deletePublishEvent(event.eventType)"
                >
                  <a-button type="link" size="small" danger>删除</a-button>
                </a-popconfirm>
              </div>
            </a-card>
          </div>
        </div>
      </a-card>

      <!-- 订阅事件 -->
      <a-card title="订阅事件" class="events-card">
        <div class="subscribe-events">
          <a-empty
            v-if="!events?.subscribe?.length"
            description="暂无订阅事件"
          />

          <div v-else class="events-list">
            <a-card
              v-for="subscription in events.subscribe"
              :key="subscription.eventType"
              class="event-card"
              size="small"
            >
              <template #title>
                <div class="event-title">
                  <span>{{ subscription.eventType }}</span>
                  <a-tag color="blue" size="small">订阅</a-tag>
                </div>
              </template>

              <div class="subscription-info">
                <p>
                  <strong>处理器:</strong>
                  {{ getHandlerDescription(subscription.handler) }}
                </p>
                <p v-if="subscription.filter">
                  <strong>过滤器:</strong> {{ subscription.filter }}
                </p>
              </div>

              <div class="event-actions">
                <a-button
                  type="link"
                  size="small"
                  @click="editSubscribeEvent(subscription)"
                >
                  编辑
                </a-button>
                <a-popconfirm
                  title="确定要删除这个订阅事件吗？"
                  @confirm="deleteSubscribeEvent(subscription.eventType)"
                >
                  <a-button type="link" size="small" danger>删除</a-button>
                </a-popconfirm>
              </div>
            </a-card>
          </div>
        </div>
      </a-card>
    </div>

    <!-- 添加发布事件模态框 -->
    <a-modal
      v-model:open="publishModalVisible"
      title="添加发布事件"
      @ok="savePublishEvent"
      @cancel="cancelPublishEvent"
    >
      <a-form :model="publishForm" layout="vertical">
        <a-form-item label="事件类型" name="eventType">
          <a-input
            v-model:value="publishForm.eventType"
            placeholder="请输入事件类型"
          />
        </a-form-item>
        <a-form-item label="事件描述" name="description">
          <a-textarea
            v-model:value="publishForm.description"
            placeholder="请输入事件描述"
          />
        </a-form-item>
        <a-form-item label="事件数据Schema" name="schema">
          <a-textarea
            v-model:value="publishForm.schema"
            placeholder="请输入事件数据Schema（JSON格式）"
            :rows="4"
          />
        </a-form-item>
      </a-form>
    </a-modal>

    <!-- 添加订阅事件模态框 -->
    <a-modal
      v-model:open="subscribeModalVisible"
      :title="editingSubscription ? '编辑订阅事件' : '添加订阅事件'"
      width="800px"
      @ok="saveSubscribeEvent"
      @cancel="cancelSubscribeEvent"
    >
      <a-form :model="subscribeForm" layout="vertical">
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="事件类型" name="eventType">
              <a-input
                v-model:value="subscribeForm.eventType"
                placeholder="请输入事件类型"
              />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="订阅模式" name="mode">
              <a-select
                v-model:value="subscribeForm.mode"
                placeholder="请选择订阅模式"
              >
                <a-select-option value="SYNC">同步</a-select-option>
                <a-select-option value="ASYNC">异步</a-select-option>
                <a-select-option value="BATCH">批量</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
        </a-row>

        <a-form-item label="事件过滤器" name="filter">
          <a-input
            v-model:value="subscribeForm.filter"
            placeholder="请输入事件过滤器（可选）"
          />
        </a-form-item>

        <!-- 处理器配置 -->
        <a-form-item label="事件处理器" name="handler">
          <div class="handler-editor">
            <a-button @click="addHandlerAction" type="dashed" block>
              <IconifyIcon icon="ant-design:plus-outlined" />
              添加处理动作
            </a-button>

            <div v-if="subscribeForm.handler.actions" class="actions-list">
              <div
                v-for="(action, index) in subscribeForm.handler.actions"
                :key="index"
                class="action-item"
              >
                <a-row :gutter="8">
                  <a-col :span="6">
                    <a-select
                      v-model:value="action.type"
                      placeholder="动作类型"
                    >
                      <a-select-option value="CALL_BEHAVIOR">
                        调用行为
                      </a-select-option>
                      <a-select-option value="STATE_CHANGE">
                        状态变更
                      </a-select-option>
                      <a-select-option value="API_CALL">
                        API调用
                      </a-select-option>
                      <a-select-option value="NOTIFICATION">
                        通知
                      </a-select-option>
                      <a-select-option value="LOG">日志记录</a-select-option>
                    </a-select>
                  </a-col>
                  <a-col :span="12">
                    <a-input
                      v-model:value="action.params"
                      placeholder="参数配置（JSON格式）"
                    />
                  </a-col>
                  <a-col :span="4">
                    <a-space>
                      <a-button
                        v-if="index > 0"
                        type="text"
                        @click="moveHandlerAction(index, 'up')"
                      >
                        ↑
                      </a-button>
                      <a-button
                        v-if="index < subscribeForm.handler.actions.length - 1"
                        type="text"
                        @click="moveHandlerAction(index, 'down')"
                      >
                        ↓
                      </a-button>
                      <a-button
                        type="text"
                        danger
                        @click="removeHandlerAction(index)"
                      >
                        <IconifyIcon icon="ant-design:delete-outlined" />
                      </a-button>
                    </a-space>
                  </a-col>
                </a-row>
              </div>
            </div>
          </div>
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<style lang="less" scoped>
.resource-events {
  .events-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;

    h3 {
      margin: 0;
    }
  }

  .events-content {
    .events-card {
      margin-bottom: 16px;

      &:last-child {
        margin-bottom: 0;
      }
    }

    .events-list {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
      gap: 12px;
    }

    .event-card {
      .event-title {
        display: flex;
        justify-content: space-between;
        align-items: center;
      }

      .subscription-info {
        margin-bottom: 8px;

        p {
          margin: 4px 0;
          font-size: 12px;
        }
      }

      .event-actions {
        display: flex;
        gap: 4px;
      }
    }
  }

  .handler-editor {
    .actions-list {
      margin-top: 12px;

      .action-item {
        margin-bottom: 8px;
        padding: 8px;
        border: 1px solid #f0f0f0;
        border-radius: 4px;
        background: #fafafa;
      }
    }
  }
}
</style>
